#ifndef DW_BASE_SINGLETON_INL
#	define DW_BASE_SINGLETON_INL

#include "base/assert.h"

namespace dw {
	namespace base {

template< typename T, bool AutoCreate >
/*static*/ inline T& Singleton< T, AutoCreate >::createInstance()
{
	dwStaticAssert(!AutoCreate, CannotCallCreateInstanceOnAnAutoCreateSingleton);
	dwAssert(m_instance == NULL, "Invalid call to createInstance, singleton has already been created");

	m_instance = new T();

	return *m_instance;
}

template< typename T, bool AutoCreate >
/*static*/ inline void Singleton< T, AutoCreate >::destroyInstance()
{
	dwStaticAssert(!AutoCreate, CannotCallDestroyInstanceOnAnAutoCreateSingleton);
	dwAssert(m_instance != NULL, "Invalid call to destroyInstance, singleton has never been created");

	delete m_instance;
	m_instance = NULL;
}

template< typename T, bool AutoCreate >
/*static*/ inline T& Singleton< T, AutoCreate >::getInstance()
{
	dwAssert(m_instance != NULL || AutoCreate, "Invalid call to getInstance on an explicit created singleton");

	if (m_instance == NULL && AutoCreate)
	{
		m_instance = new T();
	}

	return *m_instance;
}

template< typename T, bool AutoCreate >
inline Singleton< T, AutoCreate >::Singleton()
{
	dwAssert(m_instance == NULL, "Invalid call to Singleton constructor");
}

template< typename T, bool AutoCreate >
inline Singleton< T, AutoCreate >::~Singleton()
{
	dwAssert(m_instance != NULL, "Invalid call to Singleton destructor");
}

template< typename T, bool AutoCreate >
/*static*/ T* Singleton< T, AutoCreate >::m_instance = NULL;

	} // namespace base
} // namespace dw

#endif // !DW_BASE_SINGLETON_INL
